﻿using OSGeo.GDAL;
using RemoteSensingImageDirectServer.Untils.Extensions;
using RemoteSensingImageDirectServer.Untils.ScopeSpace;
using System.Data;

namespace RemoteSensingImageDirectServer.Untils.Tool
{
    public static class GdalTool
    {
        /// <summary>
        /// Gdal内存驱动
        /// </summary>
        private static OSGeo.GDAL.Driver MEMDriver = Gdal.GetDriverByName("MEM");

        /// <summary>
        /// 在虚拟内存里创建栅格
        /// </summary>
        /// <param name="name">栅格名称</param>
        /// <param name="xSize">x轴大小</param>
        /// <param name="ySize">y轴大小</param>
        /// <param name="bandCount"></param>
        /// <param name="dataType"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public static Dataset CreateMEMDataset(string name,int xSize,int ySize,int bandCount,DataType dataType, string[] options = null) 
        {
            return MEMDriver.Create(name, xSize, ySize, 1, DataType.GDT_Byte, options);
        }

        /// <summary>
        /// 从文件数据中创建一个warp投影对象
        /// </summary>
        /// <param name="warpfile">warp文件的保存路径</param>
        /// <param name="file">包含了全路径的栅格文件</param>
        /// <param name="epsg">投影的EPSG的编码(可选)</param>
        /// <param name="callback">执行函数中的回调函数(可选)</param>
        /// <returns>返回一个投影后的dataset对象</returns>
        public static Dataset ExecuteWarpByFile(string warpfile, string file, int epsg = 4326, Gdal.GDALProgressFuncDelegate? callback = null)
        {
            List<Dataset> datasetList = new List<Dataset>();

            datasetList.Add(Gdal.Open(file, Access.GA_ReadOnly));

            var dataset = Gdal.Warp(warpfile, datasetList.ToArray(),
                new GDALWarpAppOptions(new string[] { "-t_srs", $"EPSG:{epsg}", "-overwrite", "-r", "bilinear" }),
                callback, $"project");

            datasetList.Free();

            return dataset;
        }

        /// <summary>
        /// 从一组文件数据中创建一个warp投影对象
        /// </summary>
        /// <param name="warpfile">warp文件的保存路径</param>
        /// <param name="files">包含了全路径的栅格文件列表</param>
        /// <param name="epsg">投影的EPSG的编码(可选)</param>
        /// <param name="callback">执行函数中的回调函数(可选)</param>
        /// <returns>返回一个投影后的dataset对象</returns>
        public static Dataset ExecuteWarpByFiles(string warpfile, string[] files, int epsg = 4326, Gdal.GDALProgressFuncDelegate? callback = null)
        {
            List<Dataset> datasetList = new List<Dataset>();
            foreach (var file in files)
            {
                datasetList.Add(Gdal.Open(file, Access.GA_ReadOnly));
            }

            var dataset = Gdal.Warp(warpfile, datasetList.ToArray(),
                new GDALWarpAppOptions(new string[] { "-t_srs", $"EPSG:{epsg}", "-overwrite", "-r", "bilinear" }),
                callback, $"project");


            datasetList.Free();

            return dataset;
        }

        /// <summary>
        /// 从一组dataset数据中创建一个warp投影对象
        /// </summary>
        /// <param name="warpfile">warp文件的保存路径</param>
        /// <param name="ds">dataset数据</param>
        /// <param name="epsg">投影的EPSG的编码(可选)</param>
        /// <param name="callback">执行函数中的回调函数(可选)</param>
        /// <returns>返回一个投影后的dataset对象</returns>
        public static Dataset ExecuteWarpByDataset(string warpfile, Dataset ds, int epsg = 4326, Gdal.GDALProgressFuncDelegate? callback = null)
        {
            List<Dataset> datasetList = new List<Dataset>();

            datasetList.Add(ds);

            var dataset = Gdal.Warp(warpfile, datasetList.ToArray(),
                new GDALWarpAppOptions(new string[] { "-t_srs", $"EPSG:{epsg}", "-overwrite", "-r", "bilinear" }),
                callback, $"project");

            return dataset;
        }

        /// <summary>
        /// 从一组dataset数据中创建一个warp投影对象
        /// </summary>
        /// <param name="warpfile">warp文件的保存路径</param>
        /// <param name="datasets">dataset数组</param>
        /// <param name="epsg">投影的EPSG的编码(可选)</param>
        /// <param name="callback">执行函数中的回调函数(可选)</param>
        /// <returns>返回一个投影后的dataset对象</returns>
        public static Dataset ExecuteWarpByDatasets(string warpfile, Dataset[] datasets, int epsg = 4326, Gdal.GDALProgressFuncDelegate? callback = null)
        {
            var dataset = Gdal.Warp(warpfile, datasets,
                new GDALWarpAppOptions(new string[] { "-t_srs", $"EPSG:{epsg}", "-overwrite", "-r", "bilinear" }),
                callback, $"project");

            return dataset;
        }


        /// <summary>
        /// 从文件中创建vrt虚拟图层
        /// </summary>
        /// <param name="vrtfile">vrt文件的保存路径</param>
        /// <param name="file">包含了全路径的栅格文件</param>
        /// <param name="callback">执行函数中的回调函数(可选)</param>
        /// <returns>返回一个vrt虚拟图层对象</returns>
        public static Dataset ExecuteVrtByFile(string vrtfile, string file, Gdal.GDALProgressFuncDelegate? callback = null)
        {

            var dataset = Gdal.wrapper_GDALBuildVRT_names(
               vrtfile,
               new string[] { file },
               new GDALBuildVRTOptions(
                   new string[] { "bilinear", "-srcnodata", "0 0 0", "-vrtnodata", "0 0 0", "-overwrite"
                   }),
              callback, "buildvrt");

            return dataset;
        }

        /// <summary>
        /// 从一组文件中创建vrt虚拟图层
        /// </summary>
        /// <param name="vrtfile">vrt文件的保存路径</param>
        /// <param name="files">包含了全路径的栅格文件列表</param>
        /// <param name="callback">执行函数中的回调函数(可选)</param>
        /// <returns>返回一个vrt虚拟图层对象</returns>
        public static Dataset ExecuteVrtByFiles(string vrtfile, string[] files, Gdal.GDALProgressFuncDelegate? callback = null)
        {

            var dataset = Gdal.wrapper_GDALBuildVRT_names(
               vrtfile,
              files,
               new GDALBuildVRTOptions(
                   new string[] { "bilinear", "-srcnodata", "0 0 0", "-vrtnodata", "0 0 0", "-overwrite"
                   }),
              callback, "buildvrt");

            return dataset;
        }
    }
}
